# coding: utf-8
from pathlib import Path
from string import Template

import pytest

from common import (pytest_config, logger, report_html, report_json, compress_folder_shutil, report_dir,
                    DingDingClient, cache_json_path, MinioClient, json_read, json_write, WeChatClient, send_email)
from utils import process_decode


def main(
        pytest_args=None,
        open_: bool = False,
        server: bool = False,
        dingding: bool = False,
        wechat: bool = False,
        email: bool = False,
        minio: bool = False,
):
    """
    主函数
    :param pytest_args: pytest参数列表
    :param open_: 是否打开测试报告
    :param server: 是否启动测试报告服务器
    :param dingding: 是否发送测试报告到钉钉
    :param wechat: 是否发送测试报告到微信
    :param email: 是否发送测试报告到邮箱
    :param minio: 是否上传测试报告到Minio
    :return:
    """
    if pytest_args is None:
        pytest_args = []
    if open_ is True and server is True:
        raise ValueError('open_ 和 server 参数不能同时为True')

    # 运行所有测试用例
    pytest.main(
        [
            *pytest_args,
            '-p', 'no: warnings',
            '--alluredir', str(report_json),
            '-W', 'ignore:Module already imported:pytest.PytestWarning',
        ]
    )
    logger.info('测试用例执行完成！')

    # Generate Allure report
    allure_path = pytest_config.auto_test_setting.allure_app_path
    allure_cmd = f'{allure_path} generate {report_json} -o {report_html} --clean'
    logger.debug(f'Allure命令：{allure_cmd}')
    process_decode(allure_cmd)
    logger.info('测试报告生成完成！')

    # 创建压缩文件
    logger.info('创建测试报告压缩文件...')
    zip_path = report_html.with_suffix('.zip')
    logger.debug(f'源文件路径：{zip_path}')
    logger.info(f'压缩文件路径：{zip_path}')
    compress_folder_shutil(report_html, report_html)
    logger.info('测试报告压缩完成！')
    # 上传测试报告到Minio
    if minio:
        logger.info('上传测试报告到Minio...')
        path = f'{pytest_config.auto_test_setting.project_name}/{report_dir.name}/{zip_path.name}'
        logger.info(f'Minio路径：{path}')
        minio_client = MinioClient()
        link = minio_client.upload_zip(path, zip_path)
        json_write({'link': link}, cache_json_path)
        logger.info(f'测试报告上传成功！链接：{link}')
    # 生成钉钉\微信\邮件消息
    send_msg = Template(pytest_config.msg_template)
    data = json_read(cache_json_path)
    send_msg = send_msg.safe_substitute(data)
    logger.info(f'测试报告消息：{send_msg}')
    # 发送测试报告到钉钉
    if dingding:
        logger.info('发送测试报告到钉钉...')
        DingDingClient().send(send_msg.replace('\n', '\n\n'))
        logger.info('测试报告发送成功！')
    if wechat:
        logger.info('发送测试报告到微信...')
        WeChatClient().send_markdown(send_msg)
        logger.info('测试报告发送成功！')
    if email:
        logger.info('发送测试报告到邮箱...')
        contents = [send_msg, zip_path]
        send_email(contents)
        logger.info('测试报告发送成功！')
    # 打开测试报告
    args = []
    if open_ is True:
        logger.info('启动并打开测试报告...')
        args = [allure_path, 'open', str(report_html)]
    if server is True:
        logger.info('开始打开测试报告...')
        args = [allure_path, 'serve', str(report_html)]
    if args:
        process_decode(args).wait()


if __name__ == '__main__':
    # 运行所有测试用例
    case_path = Path(__file__).parent / 'test_cases' / 'web'
    main([str(case_path), '-vqs'])
